package priv.xakml.toolkit;


import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class ShaToolkit extends HashBase{

    private String mEncoding = "UTF-8";
    MessageDigest sha1_digest;

    //region Constructors
    public ShaToolkit() throws NoSuchAlgorithmException {
        init();
    }

    /**
     *
     * @param encoding 字符集编码名称
     */
    public ShaToolkit(String encoding) throws NoSuchAlgorithmException {
        init();
        mEncoding = encoding;
    }
    //endregion

    /**
     * 计算给定字符串的MD5值，结果以16进制的方式返回
     * 关于base64编码Encode和Decode编码的几种方式
     * https://www.cnblogs.com/alter888/p/9140732.html
     * @param source_content 需要计算SHA1值的原始字符串
     * @return 计算后，以十六进制的字符串方式返回
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    public String computeSha1Hash(String source_content) throws NoSuchAlgorithmException, UnsupportedEncodingException {

        byte[] source_data = source_content.getBytes(mEncoding);
        return super.computeHashToHexString(sha1_digest,source_data);
//        sha1_digest.update(source_data);
//        byte[] result = sha1_digest.sha1_digest();
//        StringBuilder stringBuilder =new StringBuilder(result.length);
//        for(byte b : result){
//            String temp = Integer.toHexString(b & 0xff);
//            if(temp.length() < 2){
//                stringBuilder.append("0");
//            }
//            stringBuilder.append(temp);
//        }
//        return stringBuilder.toString();
    }
    /**
     * 计算给定字符串的MD5值，结果以16进制的方式返回
     * 关于base64编码Encode和Decode编码的几种方式
     * https://www.cnblogs.com/alter888/p/9140732.html
     * @param source_content_bytes 需要计算SHA1值的原始字符串
     * @return 计算后，以十六进制的字符串方式返回
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    public byte[] computeSha1Hash(byte[] source_content_bytes) {
        byte[] hash_bytes = super.computeHashToBytes(sha1_digest,source_content_bytes);
        return hash_bytes;
    }
    /**
     * 计算字符串的sha1值，以base64格式返回
     */
    public String computeSha1HashToBase64(String source_content) throws UnsupportedEncodingException {
        byte[] source_content_bytes = source_content.getBytes(mEncoding);
        byte[] hash_bytes = super.computeHashToBytes(sha1_digest,source_content_bytes);
        return BinaryConverter.toBase64String(hash_bytes);
    }



    /**
     * 计算给定数据sha256格式的哈希值
     * @param plain_content_bytes 原始数据
     * @return 散列后的数据(二进制数据)
     * @throws NoSuchAlgorithmException
     */
    public byte[] computeSha256Hash(byte[] plain_content_bytes) throws NoSuchAlgorithmException {
        MessageDigest digest = this.getSha256Digest();
        return super.computeHashToBytes(digest,plain_content_bytes);
    }
    /**
     * 计算给定字符串的sha256格式的哈希值(默认编码为UTF-8)
     * @param plain_content 原始字符串类型的数据
     * @return 散列后的数据(二进制数据)
     * @throws NoSuchAlgorithmException
     */
    public byte[] computeSha256Hash(String plain_content) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        byte[] plain_content_bytes = plain_content.getBytes(mEncoding);
        MessageDigest digest = this.getSha256Digest();
        return super.computeHashToBytes(digest,plain_content_bytes);
    }
    /**
     * 计算给定数据sha256格式的哈希值
     * @param plain_content_bytes 原始数据
     * @return 以16进制表示的二进制数据
     * @throws NoSuchAlgorithmException
     */
    public String computeSha256HashToHexString(byte[] plain_content_bytes) throws NoSuchAlgorithmException {
        MessageDigest digest = this.getSha256Digest();
        return super.computeHashToHexString(digest,plain_content_bytes);
    }

    /**
     * 计算给定字符串的sha256格式哈希值
     * @param plain_content 原始字符串数据
     * @return 以16进制表示的二进制数据
     * @throws NoSuchAlgorithmException
     */
    public String computeSha256HashToHexString(String plain_content) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        byte[] plain_content_bytes = plain_content.getBytes(mEncoding);
        MessageDigest digest = this.getSha256Digest();
        return super.computeHashToHexString(digest,plain_content_bytes);
    }
    /**
     * 计算给定数据sha256格式的哈希值
     * @param plain_content_bytes 原始数据
     * @return 散列后数据的base64表示方式
     * @throws NoSuchAlgorithmException
     */
    public String computeSha256HashToBase64(byte[] plain_content_bytes) throws NoSuchAlgorithmException {
        MessageDigest digest = this.getSha256Digest();
        byte[] hash_data = super.computeHashToBytes(digest,plain_content_bytes);
        return Base64.getEncoder().encodeToString(hash_data);
    }

    /**
     * 计算给定数据sha256格式的哈希值
     * @param plain_content 原始字符串数据
     * @return 散列后数据的base64表示方式
     * @throws NoSuchAlgorithmException
     */
    public String computeSha256HashToBase64(String plain_content) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        byte[] plain_content_bytes = plain_content.getBytes(mEncoding);
        MessageDigest digest = this.getSha256Digest();
        byte[] hash_data = super.computeHashToBytes(digest,plain_content_bytes);
        return Base64.getEncoder().encodeToString(hash_data);
    }
    //region 私有方法

    /**
     * 初始化 Sha1散列的具体实现
     * @throws NoSuchAlgorithmException
     */
    private void init() throws NoSuchAlgorithmException {
        sha1_digest = MessageDigest.getInstance("SHA1");
    }
    /**
     * 生成sha256算法实现
     * @return
     * @throws NoSuchAlgorithmException
     */
    private MessageDigest getSha256Digest() throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        return digest;
    }
    //endregion
}

